#ifndef MODLUE_HXX
#define MODLUE_HXX
#include <string>
//#include <list>
using std::string;

#define MODULE_NAME_MAX_SIZE 64
#define MODULE_DATA_MAX_SIZE 128

#include "modules.hxx"

/*! \enum TestResult
 *
 *  测试值
 */
enum TestResult {
    TestResultAsPass,
    TestResultAsFail,
};

/*! \enum ModuleEnable
 *
 *  配置模块是否使能
 */
enum ModuleEnable {
    ModuleEnable,
    ModuleDisable,
};

/*! \enum ModuleAutoEnable
 *
 *  配置模块是否使能自动测试
 */
enum ModuleAutoEnable {
    ModuleAutoEnable,
    ModuleAutoDisable,
};

/*! \enum ModuleAction
 *
 *  模块执行的动作（用于观察者模式）
 */
enum ModuleActionType {
    ModuleActionSetRuntimeArg,
    ModuleActionPreinit,
    ModuleActionInit,
    ModuleActionRun,
    ModuleActionQuit,
    ModuleActionGetPendingData,
    ModuleActionGetRunResult,
    ModuleActionSetRunResult,
};

struct moduleRuntimeArg {
    int size;
    char data[MODULE_DATA_MAX_SIZE];
};

/* 模块执行的动作时，对应的参数（用于观察者模式） */
struct moduleActionArg {
    union {
        bool setRunResult;
        void *runtimeArg;
    };
};


// 模块执行结果
struct moduleResult {
    char name[MODULE_NAME_MAX_SIZE];
    int result;
};

// 模块执行结果（带数据的）
struct moduleResultData {
    char name[MODULE_NAME_MAX_SIZE];
    int  size;
    char data[MODULE_DATA_MAX_SIZE];
};


// 测试单元
class TestModule
{
public:
    /* 构造函数 */
    TestModule (void);
    TestModule(const string &name,
               enum TestResult defaultResult    = TestResultAsPass,
               enum ModuleEnable moduleEnable   = ModuleEnable,
               enum ModuleAutoEnable autoEnable = ModuleAutoEnable);
    static struct moduleRuntimeArg*newRuntimeArgFromRequest(struct moduleRequest* request);

    /* 设置属性 */
    void setName(const string &name);
    string & getName(void);
    void setOwner(class TestModulesManager* owner);
    class TestModulesManager* getOwner(void);
    void setDefaultTestResult(enum TestResult result);
    bool getDefaultTestResult(void);

    void setEnable(enum ModuleEnable enable);
    bool getEnable(void);
    void setAutomation(enum ModuleAutoEnable enable);
    bool getAutomation(void);
    void setAttrs(enum TestResult defaultResult,
                  enum ModuleEnable moduleEnable,
                  enum ModuleAutoEnable autoEnable);

    /* 设置方法 */
    void setPreInit(void (*func)(void*));
    void setInit(bool (*func)(void*));
    void setRun(bool (*func)(void*));
    void setQuit(void (*func)(void*));
    void setPendingStr(char* (*func)(void*));
    void setActionArg(void *arg); // 静态参数，在一开始的时候就已经定下来的
    void setRuntimeArg(struct moduleRuntimeArg *runtimeArg); // 动态参数，可以通过命令行等交互额外提供
    //void* getActionArg(void); // 获取参数
    void setActions(void (*preInit)(void*),
                    bool (*init)(void*),
                    bool (*run)(void*),
                    void (*quit)(void*),
                    char*(*pendingStr)(void*)=nullptr,
                    void (*action_notify)(int, void*)=nullptr);
    /* 动作方法*/
    void preInit(void);
    bool init(void);
    bool run(void);
    void quit(void);
    bool getRunResult(void);
    void setRunResult(bool result);
    char *getPendingData(void);

private:
    /* data */
    /* 测试单元的属性 */
    string m_name;
    // 测试之前的默认返回值，允许成功
    bool m_defaultTestResult;
    // 是否测试
    bool m_enable;
    // 是否自动测试
    bool m_automation;
    // 支持的测试模式（可选）
    //list<string> notAllowInMode;

    /* function */
    /* 测试动作 */
    // 注册模块时便执行的方法，常用于提前执行一些耗时的任务
    bool preInitFlag;
    void (*f_preInit)(void*);
    // 测试模块时执行的初始化方法，常用于资源初始化
    bool initFlag;
    bool (*f_init)(void*);
    // 测试模块的方法，常用于具体的测试
    bool (*f_run)(void*);
    bool m_runResult;
    // 退出测试时的方法，常用于清理工作
    void (*f_quit)(void*);
    void (*f_action_notify)(int, void*);
    char * (*f_pendingData)(void*);
    // 静态参数
    void * m_arg;
    // run时的额外参数
    struct moduleRuntimeArg* runtimeArg;
    // 复位参数（用于提高重载方法实现的维护效率）
    void resetAttr(void);
    class TestModulesManager* m_owner;
};

class TestModule;

// 通过 结构体来构造对象
struct TestModuleSt
{
    string                name;
    enum TestResult       defaultResult;
    enum ModuleEnable     moduleEnable;
    enum ModuleAutoEnable autoEnable;
    void (*preInit)(void*);
    // 测试模块时执行的初始化方法，常用于资源初始化
    bool (*init)(void*);
    // 测试模块的方法，常用于具体的测试
    bool (*run)(void*);
    // 退出测试时的方法，常用于清理工作
    void (*quit)(void*);
    char * (*getPendingData)(void*);
    // 模块执行动作前的通知
    // 用来简化类似‘提前结束模块执行’等的复杂交互
    void (*action_notify)(int, void*);
    // 静态参数
    void * arg;
    // run时的额外参数
    void *runtimeArg;
};

#endif
